/*
 * PhotonRTOS础光实时操作系统 -- 外设
 *
 * Copyright (C) 2022, 2023 国科础石(重庆)软件有限公司
 *
 * 作者: Yili Zhang <s-zhangyili@kernelsoft.com>
 *
 * License terms: GNU General Public License (GPL) version 3
 *
 */

#include <autosar/internal.h>
#include <photon/irq.h>
/*
 * 语法
 * StatusType ReadPeripheral8 (
 *       AreaIdType Area,
 *       const uint8* Address,
 *       uint8* ReadValue
 * )
 *
 * 服务 ID [hex]
 *      0x28
 *
 * 同步/异步
 *      同步（Synchronous）
 *
 * 可重入性
 *      可重入
 *
 * 参数 (in)
 *      Area 硬件外围区域参考
 *      Address 内存地址
 *
 * 参数 (inout)
 *      None
 *
 * 参数 (out)
 *      Read
 *      Value
 *      给定内存位置的内容（<地址>）
 *
 * 返回值
 *      StatusType
 *      E_OK 无错误
 *      E_OS_ID 区域 ID 超出范围（EXTENDED 状态）
 *      E_OS_VALUE 地址不属于给定区域（扩展状态）
 *      E_OS_CALLEVEL API 函数调用上下文错误（扩展状态）
 *      E_OS_ACCESS 调用任务或 ISR 不允许访问给定的
 *
 * 描述
 *      此服务返回给定内存位置 (<Address>) 的内容。
 *
 * 引用
 *      Os.h
 */
/**
 * @brief 本接口功能是读取外围硬件的8位寄存器
 * 1.只有非可信函数需要调用这个接口，可信函数可以直接读取
 * 2.首先判断区域是否是合法的，如不合法返回E_OS_ID，在扩展状态下
 * 3.区域合法之后，判断Address是否属于Area，如不属于，返回E_OS_VALUE，在扩
 * 展状态下
 * 4.判断函数调用上下文是否错误（如是否在中断上下文中），如有错误，
 * 返回E_OS_CALLEVEL，在扩展状态下
 * 5.最后判断是否有访问权限，如没有，返回E_OS_ACCESS
 *
 * @author Yili Zhang
 */
FUNC(StatusType, OS_CODE) ReadPeripheral8(
	VAR(AreaIdType, AUTOMATIC) Area,
	P2CONST(uint8, AUTOMATIC, OS_CONST) Address,
	P2VAR(uint8, TYPEDEF, OS_APPL_DATA) ReadValue)
{
	VAR(uint32, AUTOMATIC) size = (uint32)0;
	VAR(StatusType, AUTOMATIC) ret = E_OK;
	P2VAR(uint8, AUTOMATIC, OS_APPL_DATA) address = NULL;

#if defined(AUTOSAR_OS_APPLICATION)
	VAR(ApplicationType, AUTOMATIC) app_id = INVALID_OSAPPLICATION;
#endif /* defined(AUTOSAR_OS_APPLICATION) */

	CONTEXT_CHECK(ENV_TASK | ENV_CAT2_ISR)

#if defined(EXTENDED_STATUS)
	/**
	 * 在扩展模式下，检查区域参数是否合法
	 * AreaIdType类型最大为65534
	 */
#if defined(CONFIG_AUTOSAR_MAX_PERIPHERAL)
	if (Area >= CONFIG_AUTOSAR_MAX_PERIPHERAL) {
		ret = E_OS_ID;
		goto out;
	}
#else
	/*
	 *如果没有定义CONFIG_AUTOSAR_MAX_PERIPHERAL，应该报错，
	 *系统不允许不可信函数读取外围硬件
	 */
	panic("[E/Peripheral Area Error] TASK do not permission!");
#endif
	/**
	 * 在扩展模式下，判断内存地址是否合法
	 */
	address = (uint8 *)(area_peripheral[Area].address);
	size = area_peripheral[Area].size;
	if ((Address < address) || (Address >= (address + size))) {
		ret = E_OS_VALUE;
		goto out;
	}
	/**
	 * 判断是否在中断上下文中，如果在，则报E_OS_CALLEVEL
	 */
	if (in_interrupt()) {
		ret = E_OS_CALLEVEL;
		goto out;
	}

#if defined(AUTOSAR_OS_APPLICATION)
	/**
	 * 判断该application权限是否满足，如不满足则报E_OS_ACCESS
	 * 目前只允许可信application进行外设访问
	 */
	app_id = GetApplicationID();
	if (app_id < INVALID_OSAPPLICATION) {
		/*如果不是可信的application，那么拒绝其对外设的访问*/
		if (!autosar_os_app[app_id].if_trusted) {
			ret = E_OS_ACCESS;
			goto out;
		}
	} else {
		/*当前不在application中，那么就直接拒绝其访问*/
		ret = E_OS_ACCESS;
		goto out;
	}
#endif /* defined(AUTOSAR_OS_APPLICATION) */
#endif

	/**
	 * 以上全部判断完成后，由将寄存器中的值读入到ReadValue中
	 */

	*ReadValue = *(uint8 *volatile)Address;

out:
	return ret;
}

/*
 * 语法
 * StatusType ReadPeripheral16 (
 *       AreaIdType Area,
 *       const uint16* Address,
 *       uint16* ReadValue
 * )
 *
 * 服务 ID [hex]
 *      0x28
 *
 * 同步/异步
 *      同步（Synchronous）
 *
 * 可重入性
 *      可重入
 *
 * 参数 (in)
 *      Area 硬件外围区域参考
 *      Address 内存地址
 *
 * 参数 (inout)
 *      None
 *
 * 参数 (out)
 *      Read
 *      Value
 *      给定内存位置的内容（<地址>）
 *
 * 返回值
 *      StatusType
 *      E_OK 无错误
 *      E_OS_ID 区域 ID 超出范围（EXTENDED 状态）
 *      E_OS_VALUE 地址不属于给定区域（扩展状态）
 *      E_OS_CALLEVEL API 函数调用上下文错误（扩展状态）
 *      E_OS_ACCESS 调用任务或 ISR 不允许访问给定的
 *
 * 描述
 *      此服务返回给定内存位置 (<Address>) 的内容。
 *
 * 引用
 *      Os.h
 */

FUNC(StatusType, OS_CODE) ReadPeripheral16(
	VAR(AreaIdType, AUTOMATIC) Area,
	P2CONST(uint16, AUTOMATIC, OS_CONST) Address,
	P2VAR(uint16, TYPEDEF, OS_APPL_DATA) ReadValue)
{
	VAR(uint32, AUTOMATIC) size = (uint32)0;
	VAR(StatusType, AUTOMATIC) ret = E_OK;
	P2VAR(uint16, AUTOMATIC, OS_APPL_DATA) address = NULL;

#if defined(AUTOSAR_OS_APPLICATION)
	VAR(ApplicationType, AUTOMATIC) app_id = INVALID_OSAPPLICATION;
#endif /* defined(AUTOSAR_OS_APPLICATION) */

	CONTEXT_CHECK(ENV_TASK | ENV_CAT2_ISR)

#if defined(EXTENDED_STATUS)
	/**
	 * 在扩展模式下，检查区域参数是否合法
	 * AreaIdType类型最大为65534
	 */
#if defined(CONFIG_AUTOSAR_MAX_PERIPHERAL)
	if (Area >= CONFIG_AUTOSAR_MAX_PERIPHERAL) {
		ret = E_OS_ID;
		goto out;
	}
#else
	/*
	 *如果没有定义CONFIG_AUTOSAR_MAX_PERIPHERAL，应该报错，
	 *系统不允许不可信函数读取外围硬件
	 */
	panic("[E/Peripheral Area Error] TASK do not permission!");
#endif
	/**
	 * 在扩展模式下，判断内存地址是否合法
	 */
	address = (uint16 *)(area_peripheral[Area].address);
	size = area_peripheral[Area].size;
	if ((Address < address) || (Address >= (uint16 *)(((uint8 *)address + size)))) {
		ret = E_OS_VALUE;
		goto out;
	}
	/**
	 * 判断是否在中断上下文中，如果在，则报E_OS_CALLEVEL
	 */
	if (in_interrupt()) {
		ret = E_OS_CALLEVEL;
		goto out;
	}

#if defined(AUTOSAR_OS_APPLICATION)
	/**
	 * 判断该application权限是否满足，如不满足则报E_OS_ACCESS
	 * 目前只允许可信application进行外设访问
	 */
	app_id = GetApplicationID();
	if (app_id < INVALID_OSAPPLICATION) {
		/*如果不是可信的application，那么拒绝其对外设的访问*/
		if (!autosar_os_app[app_id].if_trusted) {
			ret = E_OS_ACCESS;
			goto out;
		}
	} else {
		/*当前不在application中，那么就直接拒绝其访问*/
		ret = E_OS_ACCESS;
		goto out;
	}
#endif /* defined(AUTOSAR_OS_APPLICATION) */
#endif

	/**
	 * 以上全部判断完成后，由将寄存器中的值读入到ReadValue中
	 */

	*ReadValue = *(uint16 *volatile)Address;

out:
	return ret;
}

/*
 * 语法
 * StatusType ReadPeripheral32 (
 *       AreaIdType Area,
 *       const uint32* Address,
 *       uint32* ReadValue
 * )
 *
 * 服务 ID [hex]
 *      0x28
 *
 * 同步/异步
 *      同步（Synchronous）
 *
 * 可重入性
 *      可重入
 *
 * 参数 (in)
 *      Area 硬件外围区域参考
 *      Address 内存地址
 *
 * 参数 (inout)
 *      None
 *
 * 参数 (out)
 *      Read
 *      Value
 *      给定内存位置的内容（<地址>）
 *
 * 返回值
 *      StatusType
 *      E_OK 无错误
 *      E_OS_ID 区域 ID 超出范围（EXTENDED 状态）
 *      E_OS_VALUE 地址不属于给定区域（扩展状态）
 *      E_OS_CALLEVEL API 函数调用上下文错误（扩展状态）
 *      E_OS_ACCESS 调用任务或 ISR 不允许访问给定的
 *
 * 描述
 *      此服务返回给定内存位置 (<Address>) 的内容。
 *
 * 引用
 *      Os.h
 */


FUNC(StatusType, OS_CODE) ReadPeripheral32(
	VAR(AreaIdType, AUTOMATIC) Area,
	P2CONST(uint32, AUTOMATIC, OS_CONST) Address,
	P2VAR(uint32, TYPEDEF, OS_APPL_DATA) ReadValue)
{
	VAR(uint32, AUTOMATIC) size = (uint32)0;
	VAR(StatusType, AUTOMATIC) ret = E_OK;
	P2VAR(uint32, AUTOMATIC, OS_APPL_DATA) address = NULL;

#if defined(AUTOSAR_OS_APPLICATION)
	VAR(ApplicationType, AUTOMATIC) app_id = INVALID_OSAPPLICATION;
#endif /* defined(AUTOSAR_OS_APPLICATION) */

	CONTEXT_CHECK(ENV_TASK | ENV_CAT2_ISR)

#if defined(EXTENDED_STATUS)
	/**
	 * 在扩展模式下，检查区域参数是否合法
	 * AreaIdType类型最大为65534
	 */
#if defined(CONFIG_AUTOSAR_MAX_PERIPHERAL)
	if (Area >= CONFIG_AUTOSAR_MAX_PERIPHERAL) {
		ret = E_OS_ID;
		goto out;
	}
#else
	/*
	 *如果没有定义CONFIG_AUTOSAR_MAX_PERIPHERAL，应该报错，
	 *系统不允许不可信函数读取外围硬件
	 */
	panic("[E/Peripheral Area Error] TASK do not permission!");
#endif
	/**
	 * 在扩展模式下，判断内存地址是否合法
	 */
	address = (uint32 *)(area_peripheral[Area].address);
	size = area_peripheral[Area].size;
	if ((Address < address) || (Address >= (uint32 *)(((uint8 *)address + size)))) {
		ret = E_OS_VALUE;
		goto out;
	}
	/**
	 * 判断是否在中断上下文中，如果在，则报E_OS_CALLEVEL
	 */
	if (in_interrupt()) {
		ret = E_OS_CALLEVEL;
		goto out;
	}

#if defined(AUTOSAR_OS_APPLICATION)
	/**
	 * 判断该application权限是否满足，如不满足则报E_OS_ACCESS
	 * 目前只允许可信application进行外设访问
	 */
	app_id = GetApplicationID();
	if (app_id < INVALID_OSAPPLICATION) {
		/*如果不是可信的application，那么拒绝其对外设的访问*/
		if (!autosar_os_app[app_id].if_trusted) {
			ret = E_OS_ACCESS;
			goto out;
		}
	} else {
		/*当前不在application中，那么就直接拒绝其访问*/
		ret = E_OS_ACCESS;
		goto out;
	}
#endif /* defined(AUTOSAR_OS_APPLICATION) */
#endif
	/**
	 * 以上全部判断完成后，由将寄存器中的值读入到ReadValue中
	 */

	*ReadValue = *(uint32 *volatile)Address;

out:
	return ret;
}

/*
 * 语法
 *   StatusType WritePeripheral8 (
 *      AreaIdType Area,
 *      uint8* Address,
 *      uint8 WriteValue
 *  )
 *
 * 服务 ID [hex]
 *      0x28
 *
 * 同步/异步
 *      同步（Synchronous）
 *
 * 可重入性
 *      可重入
 *
 * 参数 (in)
 *      Area 硬件外围区域参考
 *      Address 内存地址
 *
 * 参数 (inout)
 *      None
 *
 * 参数 (out)
 *      Read
 *      Value
 *      给定内存位置的内容（<地址>）
 *
 * 返回值
 *      StatusType
 *      E_OK 无错误
 *      E_OS_ID 区域 ID 超出范围（EXTENDED 状态）
 *      E_OS_VALUE 地址不属于给定区域（扩展状态）
 *      E_OS_CALLEVEL API 函数调用上下文错误（扩展状态）
 *      E_OS_ACCESS 调用任务或 ISR 不允许访问给定的
 *
 * 描述
 *      该服务将 <value> 写入给定的内存位置（<memory address>）
 *
 * 引用
 *      Os.h
 */
/**
 * @brief 本接口功能是写入外围硬件的8位寄存器
 * 1.只有非可信函数需要调用这个接口，可信函数可以直接写入
 * 2.首先判断区域是否是合法的，如不合法返回E_OS_ID，在扩展状态下
 * 3.区域合法之后，判断Address是否属于Area，如不属于，返回E_OS_VALUE，在扩
 * 展状态下
 * 4.判断函数调用上下文是否错误（如是否在中断上下文中），如有错误，
 * 返回E_OS_CALLEVEL，在扩展状态下
 * 5.最后判断是否有访问权限，如没有，返回E_OS_ACCESS
 *
 * @author Yili Zhang
 */
FUNC(StatusType, OS_CODE) WritePeripheral8(
	VAR(AreaIdType, AUTOMATIC) Area,
	P2VAR(uint8, TYPEDEF, OS_APPL_DATA) Address,
	VAR(uint8, AUTOMATIC) WriteValue)
{
	VAR(uint32, AUTOMATIC) size = (uint32)0;
	VAR(StatusType, AUTOMATIC) ret = E_OK;
	P2VAR(uint8, AUTOMATIC, OS_APPL_DATA) address = NULL;

#if defined(AUTOSAR_OS_APPLICATION)
	VAR(ApplicationType, AUTOMATIC) app_id = INVALID_OSAPPLICATION;
#endif

	CONTEXT_CHECK(ENV_TASK | ENV_CAT2_ISR)

#if defined(EXTENDED_STATUS)
	/**
	 * 在扩展模式下，检查区域参数是否合法
	 * AreaIdType类型最大为65534
	 */
#if defined(CONFIG_AUTOSAR_MAX_PERIPHERAL)
	if (Area >= CONFIG_AUTOSAR_MAX_PERIPHERAL) {
		ret = E_OS_ID;
		goto out;
	}
#else
	/*
	 *如果没有定义CONFIG_AUTOSAR_MAX_PERIPHERAL，应该报错，
	 *系统不允许不可信函数读取外围硬件
	 */
	panic("[E/Peripheral Area Error] TASK do not permission!");
#endif
	/**
	 * 在扩展模式下，判断内存地址是否合法
	 */
	address = (uint8 *)(area_peripheral[Area].address);
	size = area_peripheral[Area].size;
	if ((Address < address) || (Address >= (address + size))) {
		ret = E_OS_VALUE;
		goto out;
	}
	/**
	 * 判断是否在中断上下文中，如果在，则报E_OS_CALLEVEL
	 */
	if (in_interrupt()) {
		ret = E_OS_CALLEVEL;
		goto out;
	}

#if defined(AUTOSAR_OS_APPLICATION)
	/**
	 * 判断该application权限是否满足，如不满足则报E_OS_ACCESS
	 * 目前只允许可信application进行外设访问
	 */
	app_id = GetApplicationID();
	if (app_id < INVALID_OSAPPLICATION) {
		/*如果不是可信的application，那么拒绝其对外设的访问*/
		if (!autosar_os_app[app_id].if_trusted) {
			ret = E_OS_ACCESS;
			goto out;
		}
	} else {
		/*当前不在application中，那么就直接拒绝其访问*/
		ret = E_OS_ACCESS;
		goto out;
	}
#endif /* defined(AUTOSAR_OS_APPLICATION) */
#endif

	/**
	 * 以上全部判断完成后，将writevalue的值放入到地址对应的位置
	 */
	*Address = WriteValue;

out:
	return ret;
}

/*
 * 语法
 *   StatusType WritePeripheral16 (
 *      AreaIdType Area,
 *      uint16* Address,
 *      uint16 WriteValue
 *  )
 *
 * 服务 ID [hex]
 *      0x28
 *
 * 同步/异步
 *      同步（Synchronous）
 *
 * 可重入性
 *      可重入
 *
 * 参数 (in)
 *      Area 硬件外围区域参考
 *      Address 内存地址
 *
 * 参数 (inout)
 *      None
 *
 * 参数 (out)
 *      Read
 *      Value
 *      给定内存位置的内容（<地址>）
 *
 * 返回值
 *      StatusType
 *      E_OK 无错误
 *      E_OS_ID 区域 ID 超出范围（EXTENDED 状态）
 *      E_OS_VALUE 地址不属于给定区域（扩展状态）
 *      E_OS_CALLEVEL API 函数调用上下文错误（扩展状态）
 *      E_OS_ACCESS 调用任务或 ISR 不允许访问给定的
 *
 * 描述
 *      该服务将 <value> 写入给定的内存位置（<memory address>）
 *
 * 引用
 *      Os.h
 */
FUNC(StatusType, OS_CODE) WritePeripheral16(
	VAR(AreaIdType, AUTOMATIC) Area,
	P2VAR(uint16, TYPEDEF, OS_APPL_DATA) Address,
	VAR(uint16, AUTOMATIC) WriteValue)
{
	VAR(uint32, AUTOMATIC) size = (uint32)0;
	VAR(StatusType, AUTOMATIC) ret = E_OK;
	P2VAR(uint16, AUTOMATIC, OS_APPL_DATA) address = NULL;

#if defined(AUTOSAR_OS_APPLICATION)
	VAR(ApplicationType, AUTOMATIC) app_id = INVALID_OSAPPLICATION;
#endif /* defined(AUTOSAR_OS_APPLICATION) */

	CONTEXT_CHECK(ENV_TASK | ENV_CAT2_ISR)

#if defined(EXTENDED_STATUS)
	/**
	 * 在扩展模式下，检查区域参数是否合法
	 * AreaIdType类型最大为65534
	 */
#if defined(CONFIG_AUTOSAR_MAX_PERIPHERAL)
	if (Area >= CONFIG_AUTOSAR_MAX_PERIPHERAL) {
		ret = E_OS_ID;
		goto out;
	}
#else
	/*
	 *如果没有定义CONFIG_AUTOSAR_MAX_PERIPHERAL，应该报错，
	 *系统不允许不可信函数读取外围硬件
	 */
	panic("[E/Peripheral Area Error] TASK do not permission!");
#endif
	/**
	 * 在扩展模式下，判断内存地址是否合法
	 */
	address = (uint16 *)(area_peripheral[Area].address);
	size = area_peripheral[Area].size;
	if ((Address < address) || (Address >= (uint16 *)(((uint8 *)address + size)))) {
		ret = E_OS_VALUE;
		goto out;
	}
	/**
	 * 判断是否在中断上下文中，如果在，则报E_OS_CALLEVEL
	 */
	if (in_interrupt()) {
		ret = E_OS_CALLEVEL;
		goto out;
	}

#if defined(AUTOSAR_OS_APPLICATION)
	/**
	 * 判断该application权限是否满足，如不满足则报E_OS_ACCESS
	 * 目前只允许可信application进行外设访问
	 */
	app_id = GetApplicationID();
	if (app_id < INVALID_OSAPPLICATION) {
		/*如果不是可信的application，那么拒绝其对外设的访问*/
		if (!autosar_os_app[app_id].if_trusted) {
			ret = E_OS_ACCESS;
			goto out;
		}
	} else {
		/*当前不在application中，那么就直接拒绝其访问*/
		ret = E_OS_ACCESS;
		goto out;
	}
#endif /* defined(AUTOSAR_OS_APPLICATION) */
#endif

	/**
	 * 以上全部判断完成后，将writevalue的值放入到地址对应的位置
	 */

	*Address = WriteValue;

out:
	return ret;
}

/*
 * 语法
 *   StatusType WritePeripheral32 (
 *      AreaIdType Area,
 *      uint32* Address,
 *      uint32 WriteValue
 *  )
 *
 * 服务 ID [hex]
 *      0x28
 *
 * 同步/异步
 *      同步（Synchronous）
 *
 * 可重入性
 *      可重入
 *
 * 参数 (in)
 *      Area 硬件外围区域参考
 *      Address 内存地址
 *
 * 参数 (inout)
 *      None
 *
 * 参数 (out)
 *      Read
 *      Value
 *      给定内存位置的内容（<地址>）
 *
 * 返回值
 *      StatusType
 *      E_OK 无错误
 *      E_OS_ID 区域 ID 超出范围（EXTENDED 状态）
 *      E_OS_VALUE 地址不属于给定区域（扩展状态）
 *      E_OS_CALLEVEL API 函数调用上下文错误（扩展状态）
 *      E_OS_ACCESS 调用任务或 ISR 不允许访问给定的
 *
 * 描述
 *      该服务将 <value> 写入给定的内存位置（<memory address>）
 *
 * 引用
 *      Os.h
 */
FUNC(StatusType, OS_CODE) WritePeripheral32(
	VAR(AreaIdType, AUTOMATIC) Area,
	P2VAR(uint32, TYPEDEF, OS_APPL_DATA) Address,
	VAR(uint32, AUTOMATIC) WriteValue)
{
	VAR(uint32, AUTOMATIC) size = (uint32)0;
	VAR(StatusType, AUTOMATIC) ret = E_OK;
	P2VAR(uint32, AUTOMATIC, OS_APPL_DATA) address = NULL;

#if defined(AUTOSAR_OS_APPLICATION)
	VAR(ApplicationType, AUTOMATIC) app_id = INVALID_OSAPPLICATION;
#endif /* defined(AUTOSAR_OS_APPLICATION) */

	CONTEXT_CHECK(ENV_TASK | ENV_CAT2_ISR)

#if defined(EXTENDED_STATUS)
	/**
	 * 在扩展模式下，检查区域参数是否合法
	 * AreaIdType类型最大为65534
	 */
#if defined(CONFIG_AUTOSAR_MAX_PERIPHERAL)
	if (Area >= CONFIG_AUTOSAR_MAX_PERIPHERAL) {
		ret = E_OS_ID;
		goto out;
	}
#else
	/*
	 *如果没有定义CONFIG_AUTOSAR_MAX_PERIPHERAL，应该报错，
	 *系统不允许不可信函数读取外围硬件
	 */
	panic("[E/Peripheral Area Error] TASK do not permission!");
#endif
	/**
	 * 在扩展模式下，判断内存地址是否合法
	 */
	address = (uint32 *)(area_peripheral[Area].address);
	size = area_peripheral[Area].size;
	if ((Address < address) || (Address >= (uint32 *)(((uint8 *)address + size)))) {
		ret = E_OS_VALUE;
		goto out;
	}
	/**
	 * 判断是否在中断上下文中，如果在，则报E_OS_CALLEVEL
	 */
	if (in_interrupt()) {
		ret = E_OS_CALLEVEL;
		goto out;
	}

#if defined(AUTOSAR_OS_APPLICATION)
	/**
	 * 判断该application权限是否满足，如不满足则报E_OS_ACCESS
	 * 目前只允许可信application进行外设访问
	 */
	app_id = GetApplicationID();
	if (app_id < INVALID_OSAPPLICATION) {
		/*如果不是可信的application，那么拒绝其对外设的访问*/
		if (!autosar_os_app[app_id].if_trusted) {
			ret = E_OS_ACCESS;
			goto out;
		}
	} else {
		/*当前不在application中，那么就直接拒绝其访问*/
		ret = E_OS_ACCESS;
		goto out;
	}
#endif /* defined(AUTOSAR_OS_APPLICATION) */
#endif

	/**
	 * 以上全部判断完成后，将writevalue的值放入到地址对应的位置
	 */

	*Address = WriteValue;

out:
	return ret;
}

/*
 * 语法
 *   StatusType ModifyPeripheral8 (
 *       AreaIdType Area,
 *       uint8* Address,
 *       uint8 Clearmask,
 *       uint8 Setmask
 *)
 *
 * 服务 ID [hex]
 *      0x28
 *
 * 同步/异步
 *      同步（Synchronous）
 *
 * 可重入性
 *      可重入
 *
 * 参数 (in)
 *      Area 硬件外围区域参考
 *      Address 内存地址
 *      Clearmask 内存地址将由位与修改
 *       Setmask 内存地址将由位或修改
 *
 * 参数 (inout)
 *      None
 *
 * 参数 (out)
 *      None
 *
 * 返回值
 *      StatusType
 *      E_OK 无错误
 *      E_OS_ID 区域 ID 超出范围（EXTENDED 状态）
 *      E_OS_VALUE 地址不属于给定区域（扩展状态）
 *      E_OS_CALLEVEL API 函数调用上下文错误（扩展状态）
 *      E_OS_ACCESS 调用任务或 ISR 不允许访问给定的
 *
 * 描述
 *      此服务使用以下公式修改给定的内存位置 (<memory address>)：*<Address> =
 *  ((*<Address> & <clearmask>) | <setmask>)
 *
 * 引用
 *      Os.h
 */
/**
 * @brief 本接口功能是修改外围硬件的地址
 * 1.只有非可信函数需要调用这个接口，可信函数可以直接读取
 * 2.首先判断区域是否是合法的，如不合法返回E_OS_ID，在扩展状态下
 * 3.区域合法之后，判断Address是否属于Area，如不属于，返回E_OS_VALUE，在扩
 * 展状态下
 * 4.判断函数调用上下文是否错误（如是否在中断上下文中），如有错误，
 * 返回E_OS_CALLEVEL，在扩展状态下
 * 5.最后判断是否有访问权限，如没有，返回E_OS_ACCESS
 *
 * @author Yili Zhang
 */
FUNC(StatusType, OS_CODE) ModifyPeripheral8(
	VAR(AreaIdType, AUTOMATIC) Area,
	P2VAR(uint8, TYPEDEF, OS_APPL_DATA) Address,
	VAR(uint8, AUTOMATIC) Clearmask,
	VAR(uint8, AUTOMATIC) Setmask)
{
	VAR(uint32, AUTOMATIC) size = (uint32)0;
	VAR(StatusType, AUTOMATIC) ret = E_OK;
	P2VAR(uint8, AUTOMATIC, OS_APPL_DATA) address = NULL;

#if defined(AUTOSAR_OS_APPLICATION)
	VAR(ApplicationType, AUTOMATIC) app_id = INVALID_OSAPPLICATION;
#endif /* defined(AUTOSAR_OS_APPLICATION) */

	CONTEXT_CHECK(ENV_TASK | ENV_CAT2_ISR)

#if defined(EXTENDED_STATUS)
/**
 * 在扩展模式下，检查区域参数是否合法
 * AreaIdType类型最大为65534
 */
#if defined(CONFIG_AUTOSAR_MAX_PERIPHERAL)
	if (Area >= CONFIG_AUTOSAR_MAX_PERIPHERAL) {
		ret = E_OS_ID;
		goto out;
	}
#else
	/*
	 *如果没有定义CONFIG_AUTOSAR_MAX_PERIPHERAL，应该报错，
	 *系统不允许不可信函数读取外围硬件
	 */
	panic("[E/Peripheral Area Error] TASK do not permission!");
#endif
	/**
	 * 在扩展模式下，判断内存地址是否合法
	 */
	address = (uint8 *)(area_peripheral[Area].address);
	size = area_peripheral[Area].size;
	if ((Address < address) || (Address >= (address + size))) {
		ret = E_OS_VALUE;
		goto out;
	}
	/**
	 * 判断是否在中断上下文中，如果在，则报E_OS_CALLEVEL
	 */
	if (in_interrupt()) {
		ret = E_OS_CALLEVEL;
		goto out;
	}

#if defined(AUTOSAR_OS_APPLICATION)
	/**
	 * 判断该application权限是否满足，如不满足则报E_OS_ACCESS
	 * 目前只允许可信application进行外设访问
	 */
	app_id = GetApplicationID();
	if (app_id < INVALID_OSAPPLICATION) {
		/*如果不是可信的application，那么拒绝其对外设的访问*/
		if (!autosar_os_app[app_id].if_trusted) {
			ret = E_OS_ACCESS;
			goto out;
		}
	} else {
		/*当前不在application中，那么就直接拒绝其访问*/
		ret = E_OS_ACCESS;
		goto out;
	}
#endif /* defined(AUTOSAR_OS_APPLICATION) */
#endif

	/**
	 * 以上全部判断完成后，修改寄存器中的内容
	 */

	*Address = (uint8)(((volatile uint8)*Address & Clearmask) | Setmask);

out:
	return ret;
}

/*
 * 语法
 *   StatusType ModifyPeripheral16 (
 *       AreaIdType Area,
 *       uint16* Address,
 *       uint16 Clearmask,
 *       uint16 Setmask
 *)
 *
 * 服务 ID [hex]
 *      0x28
 *
 * 同步/异步
 *      同步（Synchronous）
 *
 * 可重入性
 *      可重入
 *
 * 参数 (in)
 *      Area 硬件外围区域参考
 *      Address 内存地址
 *      Clearmask 内存地址将由位与修改
 *       Setmask 内存地址将由位或修改
 *
 * 参数 (inout)
 *      None
 *
 * 参数 (out)
 *      None
 *
 * 返回值
 *      StatusType
 *      E_OK 无错误
 *      E_OS_ID 区域 ID 超出范围（EXTENDED 状态）
 *      E_OS_VALUE 地址不属于给定区域（扩展状态）
 *      E_OS_CALLEVEL API 函数调用上下文错误（扩展状态）
 *      E_OS_ACCESS 调用任务或 ISR 不允许访问给定的
 *
 * 描述
 *      此服务使用以下公式修改给定的内存位置 (<memory address>)：*<Address> =
 *  ((*<Address> & <clearmask>) | <setmask>)
 *
 * 引用
 *      Os.h
 */
FUNC(StatusType, OS_CODE) ModifyPeripheral16(
	VAR(AreaIdType, AUTOMATIC) Area,
	P2VAR(uint16, TYPEDEF, OS_APPL_DATA) Address,
	VAR(uint16, AUTOMATIC) Clearmask,
	VAR(uint16, AUTOMATIC) Setmask)
{
	VAR(uint32, AUTOMATIC) size = (uint32)0;
	VAR(StatusType, AUTOMATIC) ret = E_OK;
	P2VAR(uint16, AUTOMATIC, OS_APPL_DATA) address = NULL;

#if defined(AUTOSAR_OS_APPLICATION)
	VAR(ApplicationType, AUTOMATIC) app_id = INVALID_OSAPPLICATION;
#endif /* defined(AUTOSAR_OS_APPLICATION) */

	CONTEXT_CHECK(ENV_TASK | ENV_CAT2_ISR)

#if defined(EXTENDED_STATUS)
	/**
	 * 在扩展模式下，检查区域参数是否合法
	 * AreaIdType类型最大为65534
	 */
#if defined(CONFIG_AUTOSAR_MAX_PERIPHERAL)
	if (Area >= CONFIG_AUTOSAR_MAX_PERIPHERAL) {
		ret = E_OS_ID;
		goto out;
	}
#else
	/*
	 *如果没有定义CONFIG_AUTOSAR_MAX_PERIPHERAL，应该报错，
	 *系统不允许不可信函数读取外围硬件
	 */
	panic("[E/Peripheral Area Error] TASK do not permission!");
#endif
	/**
	 * 在扩展模式下，判断内存地址是否合法
	 */
	address = (uint16 *)(area_peripheral[Area].address);
	size = area_peripheral[Area].size;
	if ((Address < address) || (Address >= (uint16 *)(((uint8 *)address + size)))) {
		ret = E_OS_VALUE;
		goto out;
	}
	/**
	 * 判断是否在中断上下文中，如果在，则报E_OS_CALLEVEL
	 */
	if (in_interrupt()) {
		ret = E_OS_CALLEVEL;
		goto out;
	}

#if defined(AUTOSAR_OS_APPLICATION)
	/**
	 * 判断该application权限是否满足，如不满足则报E_OS_ACCESS
	 * 目前只允许可信application进行外设访问
	 */
	app_id = GetApplicationID();
	if (app_id < INVALID_OSAPPLICATION) {
		/*如果不是可信的application，那么拒绝其对外设的访问*/
		if (!autosar_os_app[app_id].if_trusted) {
			ret = E_OS_ACCESS;
			goto out;
		}
	} else {
		/*当前不在application中，那么就直接拒绝其访问*/
		ret = E_OS_ACCESS;
		goto out;
	}
#endif /* defined(AUTOSAR_OS_APPLICATION) */
#endif

	/**
	 * 以上全部判断完成后，修改寄存器中的内容
	 */

	*Address = (uint16)(((volatile uint16)*Address & Clearmask) | Setmask);

out:
	return ret;
}

/*
 * 语法
 *   StatusType ModifyPeripheral32 (
 *       AreaIdType Area,
 *       uint32* Address,
 *       uint32 Clearmask,
 *       uint32 Setmask
 *)
 *
 * 服务 ID [hex]
 *      0x28
 *
 * 同步/异步
 *      同步（Synchronous）
 *
 * 可重入性
 *      可重入
 *
 * 参数 (in)
 *      Area 硬件外围区域参考
 *      Address 内存地址
 *      Clearmask 内存地址将由位与修改
 *       Setmask 内存地址将由位或修改
 *
 * 参数 (inout)
 *      None
 *
 * 参数 (out)
 *      None
 *
 * 返回值
 *      StatusType
 *      E_OK 无错误
 *      E_OS_ID 区域 ID 超出范围（EXTENDED 状态）
 *      E_OS_VALUE 地址不属于给定区域（扩展状态）
 *      E_OS_CALLEVEL API 函数调用上下文错误（扩展状态）
 *      E_OS_ACCESS 调用任务或 ISR 不允许访问给定的
 *
 * 描述
 *      此服务使用以下公式修改给定的内存位置 (<memory address>)：*<Address> =
 *  ((*<Address> & <clearmask>) | <setmask>)
 *
 * 引用
 *      Os.h
 */
FUNC(StatusType, OS_CODE) ModifyPeripheral32(
	VAR(AreaIdType, AUTOMATIC) Area,
	P2VAR(uint32, TYPEDEF, OS_APPL_DATA) Address,
	VAR(uint32, AUTOMATIC) Clearmask,
	VAR(uint32, AUTOMATIC) Setmask)
{
	VAR(uint32, AUTOMATIC) size = (uint32)0;
	VAR(StatusType, AUTOMATIC) ret = E_OK;
	P2VAR(uint32, AUTOMATIC, OS_APPL_DATA) address = NULL;

#if defined(AUTOSAR_OS_APPLICATION)
	VAR(ApplicationType, AUTOMATIC) app_id = INVALID_OSAPPLICATION;
#endif /* defined(AUTOSAR_OS_APPLICATION) */

	CONTEXT_CHECK(ENV_TASK | ENV_CAT2_ISR)

#if defined(EXTENDED_STATUS)
	/**
	 * 在扩展模式下，检查区域参数是否合法
	 * AreaIdType类型最大为65534
	 */
#if defined(CONFIG_AUTOSAR_MAX_PERIPHERAL)
	if (Area >= CONFIG_AUTOSAR_MAX_PERIPHERAL) {
		ret = E_OS_ID;
		goto out;
	}
#else
	/*
	 *如果没有定义CONFIG_AUTOSAR_MAX_PERIPHERAL，应该报错，
	 *系统不允许不可信函数读取外围硬件
	 */
	panic("[E/Peripheral Area Error] TASK do not permission!");
#endif
	/**
	 * 在扩展模式下，判断内存地址是否合法
	 */
	address = (uint32 *)(area_peripheral[Area].address);
	size = area_peripheral[Area].size;
	if ((Address < address) || (Address >= (uint32 *)(((uint8 *)address + size)))) {
		ret = E_OS_VALUE;
		goto out;
	}
	/**
	 * 判断是否在中断上下文中，如果在，则报E_OS_CALLEVEL
	 */
	if (in_interrupt()) {
		ret = E_OS_CALLEVEL;
		goto out;
	}

#if defined(AUTOSAR_OS_APPLICATION)
	/**
	 * 判断该application权限是否满足，如不满足则报E_OS_ACCESS
	 * 目前只允许可信application进行外设访问
	 */
	app_id = GetApplicationID();
	if (app_id < INVALID_OSAPPLICATION) {
		/*如果不是可信的application，那么拒绝其对外设的访问*/
		if (!autosar_os_app[app_id].if_trusted) {
			ret = E_OS_ACCESS;
			goto out;
		}
	} else {
		/*当前不在application中，那么就直接拒绝其访问*/
		ret = E_OS_ACCESS;
		goto out;
	}
#endif /* defined(AUTOSAR_OS_APPLICATION) */
#endif

	/**
	 * 以上全部判断完成后，修改寄存器中的内容
	 */

	*Address = (uint32)(((volatile uint32)*Address & Clearmask) | Setmask);

out:
	return ret;
}

#if defined(CONFIG_AUTOSAR_MAX_PERIPHERAL)
/**
 * AUTOSAR的外设区域需要使用OIL进行初始化，目前尚未实现，因此这里暂时静态初始化
 * 目前两个区域，串口和中断控制器，数组索引0为串口，索引1为中
 * 断控制器
 * 索引2为测试区域
*/
VAR(int8_t, AUTOMATIC) peripheral_test[4096] = {'\0'};

VAR(AUTOSAR_AREA_PERIPHERAL, AUTOMATIC)
area_peripheral[CONFIG_AUTOSAR_MAX_PERIPHERAL] = {

	#if defined(CONFIG_ARCH_MPS2_CORTEXM3)
		{(AreaIdType)0, (uint32 *)0x40004000, 0x1000},
		{(AreaIdType)1, (uint32 *)0xE000E100, 0x10000},
	#elif defined(CONFIG_ARCH_XILINX_CORTEXR5)
		{(AreaIdType)0, (uint32 *)0xFF000000, 0x1000},
		{(AreaIdType)1, (uint32 *)0xf9000000, 0x1000},
	#elif defined(CONFIG_ARCH_QEMU)
		{(AreaIdType)0, (uint32 *)0x9000000, 0x1000},
		{(AreaIdType)1, (uint32 *)0x8000000, 0x10000},
	#endif
	{(AreaIdType)2, (uint32 *)peripheral_test, 0x1000},
};
#endif